<template>
	<el-card style="width: 100%; position: relative; top: 60px; margin: 0 auto; min-height: calc(100vh - 60px)">
		<el-page-header @back="$route.go(-1)">
			<template #content>
				<el-tag>{{ form.name }}</el-tag>
			</template>
			<template #extra>
				<div>
					<el-button v-if="!form.isCollect" circle :icon="Star" type="primary" @click="handleCollect"></el-button>
					<el-button v-if="form.isCollect" circle :icon="Star" type="warning" @click="handleCollect"></el-button>
				</div>
			</template>
		</el-page-header>
		<el-row>
			<div style="width: 100%; display: flex; justify-content: center; margin: 10px auto; position: relative">
				<video
					ref="videoPlayer"
					:src="videoSrc"
					controls
					width="1280"
					style="position: relative"
					@play="onPlay"
					@pause="onPause"
					@ended="onEnded"
					@timeupdate="onTimeUpdate"
					@seeking="onSeeking"
					@seeked="onSeeked"
				>
					您的浏览器不支持 HTML5 视频标签。
				</video>
				<vue-danmaku
					ref="danmaku"
					:danmus="danmakuList"
					:speeds="100"
					:font-size="20"
					is-suspend
					use-slot
					style="
						position: absolute;
						top: 0;
						left: 50%;
						transform: translateX(-50%);
						width: 1280px;
						height: 720px;
						pointer-events: none;
						overflow: hidden;
						z-index: 1;
					"
				>
					<template #dm="scope">
						<span
							:style="{
								color: scope.danmu.color,
								textShadow: '1px 1px 2px rgba(0,0,0,0.5)',
								pointerEvents: 'auto'
							}"
						>
							{{ scope.danmu.text }}
						</span>
					</template>
				</vue-danmaku>
			</div>
		</el-row>
		<el-row justify="center" class="danmaku-input-container">
			<el-col :span="16">
				<div class="danmaku-input-wrap">
					<el-input
						v-model="danmakuInput"
						placeholder="输入弹幕内容（最多20字）"
						maxlength="20"
						clearable
						class="custom-danmaku-input"
						@keyup.enter="sendDanmaku"
					>
						<template #prepend>
							<div class="input-prepend-group">
								<el-button
									type="primary"
									:icon="isDanmakuVisible ? Close : View"
									circle
									class="danmaku-toggle-btn"
									@click="toggleDanmaku"
								></el-button>
								<el-color-picker v-model="danmakuColor" show-alpha :predefine="predefineColors" size="small" class="color-picker"></el-color-picker>
							</div>
						</template>
						<template #append>
							<el-button type="primary" :icon="Promotion" class="send-btn" @click="sendDanmaku">发送</el-button>
						</template>
					</el-input>
				</div>
			</el-col>
		</el-row>
		<el-row justify="center">
			<el-col :span="16" style="margin: 16px 0">
				<div class="video-description-box">
					<div class="video-description">
						{{ form.des }}
					</div>
					<div class="tags-container">
						<el-tag v-for="(tag, index) in (form.tags || '').split(',')" :key="index" size="small" type="info" style="margin: 8px 4px 0 0">
							{{ tag }}
						</el-tag>
					</div>
				</div>
			</el-col>
		</el-row>

		<div class="comment">
			<u-comment :config="config" @submit="submit">
				<template #operate="scope">
					<el-button
						v-if="systemStore.userInfo.roleNames.some(role => ['超级管理员', '员工'].includes(role))"
						:icon="Delete"
						size="small"
						@click="remove(scope.id)"
					></el-button>
				</template>
			</u-comment>
		</div>
	</el-card>
</template>

<script setup>
import { onBeforeMount, reactive, ref, onMounted, onBeforeUnmount } from 'vue'
import { Close, Delete, Promotion, Star, View } from '@element-plus/icons-vue'
import request from '@/utils/request'
import { ElMessage } from 'element-plus'
import 'md-editor-v3/lib/style.css'
import router from '@/router'
import { UComment } from 'undraw-ui'
import emoji from '@/emoji/emoji'
import useSystemStore from '@/stores/system'
import VueDanmaku from 'vue3-danmaku'

const headerTitle = ref()
const pageNum = ref(1)
const pageSize = ref(10)
const total = ref(0)
const tableData = ref([])
const multipleSelection = ref([])
const disabled = ref(true)
const dialogVisible = ref(false)
const userList = ref([])
const name = ref('')
const uid = ref('')
const statu = ref('')
const systemStore = useSystemStore()
const danmaku = ref(null)
const danmakuList = ref([])
const danmakuInput = ref('')
const danmakuColor = ref('#fff')
const danmakuType = ref(0)
const currentDanmakuIndex = ref(0)
const danmakuSortedList = ref([])
const isSeeking = ref(false)
const formSize = ref('default')
const ruleFormRef = ref()
const videoSrc = ref('')
const videoStatus = ref('未播放')
const isVideoPlaying = ref(false)
const isDanmakuVisible = ref(true)

const config = reactive({
	user: systemStore.userInfo,
	emoji: emoji,
	comments: [],
	showLevel: false,
	showHomeLink: false,
	showAddress: false,
	show: {
		level: false, // 是否显示等级
		likes: false, // 是否点赞
		address: false, // 是否显示地址
		homeLink: false, // 是否跳转个人主页地址
		reply: true // 是否显示回复按钮
	}
})

// 表单数据定义
const form = reactive({
	id: undefined,
	name: undefined,
	img: undefined,
	video: undefined,
	des: undefined,
	uid: undefined,
	statu: '未审核',
	createTime: undefined,
	isCollect: undefined
})

// 表单校验规则
const rules = reactive({
	name: [{ required: true, message: '必选项不能为空', trigger: 'blur' }],
	img: [{ required: true, message: '必选项不能为空', trigger: 'change' }],
	video: [{ required: true, message: '必选项不能为空', trigger: 'change' }],
	des: [{ required: true, message: '必选项不能为空', trigger: 'blur' }],
	uid: [{ required: true, message: '必选项不能为空', trigger: 'change' }]
})

const handleCollect = async () => {
	const entity = { vid: form.id }
	const res = await request.post(`/video/collect`, entity)
	ElMessage({
		message: res.data,
		type: 'success',
		showClose: true
	})
	await loadVideoDetail()
}

// 加载弹幕
const loadDanmaku = async () => {
	const res = await request.get(`/barrage/video/${router.currentRoute.value.query.id}`)
	danmakuSortedList.value = res.data
		.map(item => ({
			text: item.content,
			color: item.color,
			time: item.time,
			type: item.type,
			sent: false,
			channel: item.type === 0 ? 'scroll' : 'static_top'
		}))
		.sort((a, b) => a.time - b.time)

	const initialTime = videoPlayer.value?.currentTime || 0
	const firstUnsentIndex = danmakuSortedList.value.findIndex(danmu => danmu.time > initialTime)
	currentDanmakuIndex.value = firstUnsentIndex === -1 ? danmakuSortedList.value.length : firstUnsentIndex
	danmakuSortedList.value.forEach((danmu, index) => {
		danmu.sent = index < currentDanmakuIndex.value
	})
}

const predefineColors = ref(['#ff4500', '#ff8c00', '#ffd700', '#90ee90', '#00ced1', '#1e90ff', '#c71585', '#ffffff', '#000000'])

// 发送弹幕
const sendDanmaku = async () => {
	if (!systemStore.userInfo.id) {
		ElMessage.warning('请先登录后发送弹幕')
		return
	}

	if (!danmakuInput.value.trim()) {
		ElMessage.warning('弹幕内容不能为空')
		return
	}

	try {
		const barrage = {
			vid: form.id,
			content: danmakuInput.value,
			color: danmakuColor.value,
			type: danmakuType.value,
			time: (videoPlayer.value?.currentTime || 0) + 0.01
		}

		await request.post('/barrage', barrage)

		// 将新弹幕添加到排序列表而不是直接推送
		const newDanmu = {
			text: barrage.content,
			color: barrage.color,
			time: barrage.time,
			type: barrage.type,
			sent: false,
			channel: barrage.type === 0 ? 'scroll' : 'static_top'
		}

		danmakuSortedList.value.push(newDanmu)
		danmakuSortedList.value.sort((a, b) => a.time - b.time)

		if (isVideoPlaying.value && videoPlayer.value.currentTime >= newDanmu.time) {
			danmaku.value.push(newDanmu)
		}

		danmakuInput.value = ''
		ElMessage.success('弹幕发送成功')
	} catch (error) {
		ElMessage.error('弹幕发送失败：' + error.message)
	}
}

// 切换弹幕显示状态
const toggleDanmaku = () => {
	isDanmakuVisible.value = !isDanmakuVisible.value
	if (isDanmakuVisible.value) {
		danmaku.value.show()
		ElMessage.info('弹幕已开启')
	} else {
		danmaku.value.hide()
		ElMessage.info('弹幕已关闭')
	}
}

const updateDanmakuSize = () => {
	if (videoPlayer.value) {
		danmaku.value.$el.style.width = `${videoPlayer.value.offsetWidth}px`
		danmaku.value.$el.style.height = `${videoPlayer.value.offsetHeight}px`
	}
}

const onTimeUpdate = () => {
	if (!isVideoPlaying.value || !videoPlayer.value || isSeeking.value) {
		return
	}

	const currentTime = videoPlayer.value.currentTime
	const duration = videoPlayer.value.duration

	// 边界保护：当视频异常时可能返回NaN
	if (isNaN(currentTime)) {
		return
	}

	// 精确到小数点后2位进行比较
	const current = Number(currentTime.toFixed(2))

	// 从当前索引开始处理
	for (let i = currentDanmakuIndex.value; i < danmakuSortedList.value.length; i++) {
		const danmu = danmakuSortedList.value[i]
		const danmuTime = Number(danmu.time.toFixed(2))

		if (danmuTime <= current && !danmu.sent) {
			danmaku.value.push(danmu)
			danmu.sent = true
			currentDanmakuIndex.value = i + 1
		} else if (danmuTime > current) {
			break
		}
	}
}

const onSeeking = () => {
	isSeeking.value = true
	danmaku.value.pause()
}

const onSeeked = () => {
	isSeeking.value = false
	const currentTime = videoPlayer.value.currentTime

	// 重置弹幕状态并同步显示
	resetDanmakuState(currentTime)

	danmakuSortedList.value.slice(0, currentDanmakuIndex.value).forEach(danmu => {
		danmaku.value.push({ ...danmu, time: 0 })
	})
}

// 提交评论
const submit = async ({ content, parentId, finish }) => {
	// 确保 form.id 存在且有效
	if (!form.id) {
		ElMessage.error('视频ID不存在')
		return
	}

	const comment = {
		parentId: parentId || 0,
		uid: config.user.id,
		content: content,
		vid: form.id, // 确保这里正确传递了视频ID
		user: {
			username: config.user.username,
			avatar: config.user.avatar
		}
	}

	try {
		await request.post('/video/comment', comment)
		await loadVideoDetail()
		finish()
	} catch (error) {
		ElMessage.error('评论提交失败：' + error.message)
	}
}

// 删除评论
const remove = async id => {
	await request.delete(`/comment/${id}`)
	await loadVideoDetail()
}

// 加载数据
const loadVideoDetail = async () => {
	const id = router.currentRoute.value.query.id
	if (id) {
		const res = await request.get(`/video/${id}`)
		Object.assign(form, res.data)

		// 加载评论
		const commentsRes = await request.get(`/video/comment/video/${id}`)
		config.comments = commentsRes.data

		const collectRes = await request.get(`/video/collect/check?vid=${id}`)
		form.isCollect = collectRes.data
	}
}

// 分页查询方法（初始化方法，页面加载成功以后就调用的方法）
const load = async () => {
	const res = await request.get('/video/page', {
		params: {
			pageNum: pageNum.value,
			pageSize: pageSize.value,
			name: name.value,
			uid: uid.value,
			statu: statu.value
		}
	})
	pageNum.value = res.data.current
	pageSize.value = res.data.size
	total.value = res.data.total
	tableData.value = res.data.records
	//   userList
	const resuser = await request.get(`/user`)
	userList.value = resuser.data
}
// 加载页面初始化调用load方法
load()

// 清空查询数据重置方法
const handleReset = () => {
	name.value = ''
	uid.value = ''
	statu.value = ''
	load()
}

const change = async row => {
	await request.put(`/video/${row.id}`, row)
	ElMessage({
		showClose: true,
		message: '操作成功',
		type: 'success'
	})
	await load()
}
const $route = router

onBeforeMount(async () => {
	if ($route.currentRoute.value.query.id) {
		const res = await request.get(`/video/${$route.currentRoute.value.query.id}`)
		Object.assign(form, res.data)
		videoSrc.value = form.video
	}
})

// 获取视频元素引用
const videoPlayer = ref(null)

const toggleFullScreen = () => {
	const video = videoPlayer.value
	if (video.requestFullscreen) {
		video.requestFullscreen()
	} else if (video.mozRequestFullScreen) {
		// Firefox
		video.mozRequestFullScreen()
	} else if (video.webkitRequestFullscreen) {
		// Chrome, Safari and Opera
		video.webkitRequestFullscreen()
	} else if (video.msRequestFullscreen) {
		// IE/Edge
		video.msRequestFullscreen()
	}
}

const resetDanmakuState = currentTime => {
	danmaku.value.stop()
	danmakuList.value = [] // 清空所有正在显示的弹幕

	// 找到第一个时间超过当前时间的弹幕索引
	const firstUnsentIndex = danmakuSortedList.value.findIndex(danmu => danmu.time > currentTime)
	currentDanmakuIndex.value = firstUnsentIndex === -1 ? danmakuSortedList.value.length : firstUnsentIndex

	// 标记当前时间之前的所有弹幕为已发送
	danmakuSortedList.value.forEach((danmu, index) => {
		danmu.sent = index < currentDanmakuIndex.value
	})
}

const onPlay = async () => {
	isVideoPlaying.value = true
	// 首次播放时加载弹幕
	if (danmakuSortedList.value.length === 0) {
		await loadDanmaku()
	}

	// 如果是从结束状态恢复播放
	if (videoStatus.value === '播放结束') {
		danmakuSortedList.value.forEach(danmu => (danmu.sent = false))
		currentDanmakuIndex.value = 0
		danmaku.value.stop()
	}
	danmaku.value.play()
}

// 在视频暂停时暂停弹幕
const onPause = () => {
	danmaku.value.pause()
}

const onEnded = () => {
	videoStatus.value = '播放结束'
	// 重置弹幕状态
	danmakuSortedList.value.forEach(danmu => (danmu.sent = false))
	currentDanmakuIndex.value = 0
	danmaku.value.stop()
}

onBeforeMount(loadVideoDetail)

onMounted(async () => {
	window.addEventListener('resize', updateDanmakuSize)
	updateDanmakuSize()

	await loadDanmaku()

	// 仅当视频已处于播放状态时才初始化弹幕
	if (videoPlayer.value && !videoPlayer.value.paused) {
		const initTime = videoPlayer.value.currentTime
		for (let i = 0; i < danmakuSortedList.value.length; i++) {
			const danmu = danmakuSortedList.value[i]
			if (danmu.time <= initTime) {
				danmaku.value.push(danmu)
				danmu.sent = true
				currentDanmakuIndex.value = i + 1
			}
		}
	}
})

onBeforeUnmount(() => {
	window.removeEventListener('resize', updateDanmakuSize)
})
</script>

<style scoped lang="scss">
.vue-danmaku span {
	text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
	white-space: nowrap;
}

.danmaku-input-container {
	padding: 0;
}

.danmaku-input-wrap {
	background: #fff;
	padding: 12px 16px;
	border-radius: 24px;
	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

.custom-danmaku-input {
	--el-input-border-radius: 24px;
	--el-input-padding-y: 8px;
	--el-input-padding-x: 16px;

	.el-input__inner {
		font-size: 14px;
		color: #333;
	}
}

.input-prepend-group {
	display: flex;
	align-items: center;
	gap: 20px;

	.danmaku-toggle-btn {
		width: 40px;
		height: 40px;

		:deep(.el-button--primary) {
			background-color: #409eff;
			border-color: #409eff;

			&:hover {
				background-color: #66b1ff;
			}
		}
	}

	.color-picker {
		width: 120px;
		.el-color-picker__trigger {
			padding: 6px 12px;
			border-radius: 20px;
			font-size: 12px;
		}
	}
}

.send-btn {
	min-width: 64px;
	font-weight: 500;
	&:disabled {
		opacity: 0.6;
		cursor: not-allowed;
	}
}

.video-description {
	white-space: pre-line;
	word-break: break-word;
	color: #606266;
	font-size: 14px;
	line-height: 1.7;
	text-align: justify;
}

.tags-container {
	margin-top: 12px;
	display: flex;
	flex-wrap: wrap;
	justify-content: flex-start;
	align-items: center;
	gap: 4px;
}

.video-description-box {
	border: 1px solid #ebeef5;
	border-radius: 8px;
	padding: 16px;
	margin: 0 auto;
	position: relative;
	background-color: #f8f9fe;
	box-shadow: 0 2px 12px 0 rgba(255, 255, 255, 0.06);
}

.comment {
	border: 1px solid #ebeef5;
	border-radius: 8px;
	padding: 16px;
	margin: 20px auto;
	background-color: #fff;
	box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.06);

	:deep(.u-comment-head) {
		font-size: 16px;
		color: #303133;
		padding-bottom: 12px;
		border-bottom: 1px solid #ebeef5;
		margin-bottom: 16px;
	}

	:deep(.u-comment-container) {
		padding: 0 8px;
	}
}
</style>
